#pragma once

#include "../DefinesCore.hpp"
#include <vector>
#include <functional>

CYBERTRON_BEGIN

class FiniteStateMachine : public std::enable_shared_from_this<FiniteStateMachine>
{
public:
	CybertronCoreAPI FiniteStateMachine();
	CybertronCoreAPI FiniteStateMachine(const FiniteStateMachine& rhs);
	CybertronCoreAPI FiniteStateMachine& operator = (const FiniteStateMachine& rhs);
	CybertronCoreAPI virtual ~FiniteStateMachine();

	CybertronCoreAPI void addState(
		int state,
		std::function<void()> funcOnEnter = nullptr,
		std::function<void()> funcOnLeave = nullptr);

	CybertronCoreAPI void createTransition(
		int fromState,
		int toState,
		int eventId);

public:
	CybertronCoreAPI void swap(FiniteStateMachine& rhs);
	CybertronCoreAPI void clear();

	CybertronCoreAPI int getCurrentState() const;

	CybertronCoreAPI void onEvent(int eventId);

private:
	void zeroMembers();

private:
	int mCurrentState;
	std::vector<std::function<void()>> mEnterStateFunctions;
	std::vector<std::function<void()>> mLeaveStateFunctions;
	std::vector<std::vector<int>> mEventIdsToOtherStates;
};

CYBERTRON_END
